iT邦幫忙

2026 iThome 鐵人賽

DAY 24
1
Kubernetes

從零到 CKA:30 天掌握 Kubernetes 核心觀念與實作系列 第 24

Day 24|RBAC — Kubernetes 的角色權限控制

  • 分享至 

  • xImage
  •  

前言

Day 8 介紹 Secret 時,我們曾經提到 RBAC,因為 Secret 能不能被讀取,取決於使用者或 ServiceAccount 是否被授予對應權限。

經過 Day 20~23 的 Helm 系列後,我們已經能打包、管理與部署完整的應用程式。但還有一個很重要的問題:

叢集裡的每個人、每個 Pod,都可以隨意操作任何 Kubernetes 資源嗎?

答案當然是不行

就像公司裡不同角色有不同權限,例如財務可以看帳、工程師可以部署、實習生可能只有讀取權限,Kubernetes 也有一套角色權限控制機制:

RBAC(Role-Based Access Control)

今天內容包含:

  1. 為什麼需要 RBAC? —— 了解 Kubernetes 為什麼需要權限控制
  2. RBAC 核心概念 —— 認識 Role、ClusterRole、RoleBinding、ClusterRoleBinding
  3. Role 與 ClusterRole —— 定義「可以做什麼」
  4. RoleBinding 與 ClusterRoleBinding —— 定義「誰可以做」
  5. 驗證權限 —— 使用 kubectl auth can-i 測試權限
  6. ServiceAccount 實戰 —— 讓 Pod 使用特定身份存取 Kubernetes API
  7. 內建的 ClusterRole —— 認識 cluster-adminadmineditview
  8. 最小權限原則 —— 為不同場景配置適當權限
  9. 常見問題與注意事項 —— 整理 RBAC 常見錯誤與排查方式

以下操作皆在 master 節點執行。


一、為什麼需要 RBAC?

先看一個常見的權限需求:

角色 應該能做的事 不該做的事
叢集管理員 管理整個叢集 通常具備完整管理權限
開發者 在自己的 Namespace 裡部署、查看 Pod / Service 刪除其他 Namespace、修改叢集層級設定
監控系統 讀取 Pod、Node 等監控所需資訊 任意刪除或修改資源
CI/CD Pipeline 部署到指定 Namespace 操作其他 Namespace 或取得不需要的 Secret

如果沒有適當的權限控制,只要取得 Kubernetes API 的存取身分,就可能獲得超出實際需求的權限。

RBAC 的目的,就是依照使用者、ServiceAccount 或 Group 的角色,限制它們可以操作哪些資源、執行哪些動作。

💡 RBAC 是 Kubernetes 內建的 Authorization 機制之一

Kubernetes API Server 支援多種 Authorization Mode,例如 RBACNodeWebhook 等。

實務上 RBAC 是非常常見的權限管理方式,可以針對不同使用者與 ServiceAccount 授予最小必要權限。

關於 Authorization,我之後會另外開新系列深入說明。


二、RBAC 核心概念

RBAC 可以用一句話概括:

「誰(Subject)」透過「綁定(Binding)」獲得「角色(Role / ClusterRole)」中定義的權限(Rules)。

https://ithelp.ithome.com.tw/upload/images/20260821/20181928OS2sOQ8KPI.png

四個關鍵元件

元件 作用 範圍
Role 定義某個 Namespace 內可以操作哪些資源、執行哪些動作 單一 Namespace
ClusterRole 定義可跨 Namespace 使用,或針對 cluster-scoped resources 的權限 叢集層級
RoleBinding 在某個 Namespace 中,將 Role 或 ClusterRole 綁定給 Subject 單一 Namespace
ClusterRoleBinding 將 ClusterRole 綁定給 Subject,授予叢集範圍權限 全叢集

💡 簡單記法

  • Role / RoleBinding:主要處理 Namespace 範圍的權限
  • ClusterRole / ClusterRoleBinding:處理叢集層級或跨 Namespace 的權限

Subject(主體)— 誰要被授權?

RBAC 可以綁定三種 Subject:

Subject 類型 說明 常見場景
User 外部身分系統驗證後的使用者 開發者、管理員
Group 使用者群組 團隊層級權限管理
ServiceAccount Kubernetes 內提供給 Pod 使用的身分 CI/CD、監控系統、應用程式

⚠️ User 和 Group 不是 Kubernetes Resource

Kubernetes 不會替你建立或保存 User / Group,因此不能用 kubectl get users 查詢。

它們通常來自外部 Authentication 機制,例如 Client Certificate、OIDC 等;只有 ServiceAccount 是 Kubernetes 原生 Resource。


三、Role 與 ClusterRole — 定義「能做什麼」

Step 1:建立測試用的 Namespace

kubectl create namespace dev-team

Step 2:建立 Role — Namespace 層級的權限

vim dev-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev-team
  name: pod-reader
rules:
  - apiGroups: [""]          # "" 代表 core API group
    resources: ["pods"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get"]           # 允許查看 Pod 日誌
kubectl apply -f dev-role.yaml

💡 apiGroups 怎麼填?

apiGroups 用來指定資源所屬的 API Group。

常見例子:

  • "":Core API Group,例如 Pod、Service、ConfigMap、Secret
  • "apps":Deployment、StatefulSet、DaemonSet
  • "batch":Job、CronJob
  • "rbac.authorization.k8s.io":Role、ClusterRole、RoleBinding、ClusterRoleBinding

如果不確定某個資源屬於哪個 API Group,可以使用:

kubectl api-resources

查看各個 Kubernetes Resource 對應的 API Group。

Step 3:建立 ClusterRole — 全叢集層級的權限

vim cluster-monitor-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-monitor
rules:
  - apiGroups: [""]
    resources: ["pods", "nodes", "services"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["apps"]
    resources: ["deployments", "statefulsets"]
    verbs: ["get", "list", "watch"]
kubectl apply -f cluster-monitor-role.yaml

Role vs ClusterRole 使用時機

情境 選擇 原因
開發者只能操作自己的 Namespace Role 權限限定在單一 Namespace
監控系統需要讀取所有 Namespace ClusterRole 定義跨 Namespace 的權限,通常搭配 ClusterRoleBinding
操作 Node、PV 等非 Namespace 資源 ClusterRole 這些屬於 cluster-scoped resources
定義可重用的權限模板 ClusterRole 可以搭配不同 Namespace 的 RoleBinding 重複使用

四、RoleBinding 與 ClusterRoleBinding — 定義「誰能做」

Role 或 ClusterRole 只負責定義「有哪些權限」,本身不會直接授權給任何人。

還需要透過 RoleBindingClusterRoleBinding,把這些權限綁定給 User、Group 或 ServiceAccount,權限才會真正生效。

Step 4:建立 ServiceAccount

# 建立一個代表「開發者」的 ServiceAccount
kubectl create serviceaccount dev-user -n dev-team

Step 5:用 RoleBinding 綁定 Role

vim dev-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-pod-reader
  namespace: dev-team
subjects:
  - kind: ServiceAccount
    name: dev-user
    namespace: dev-team
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f dev-rolebinding.yaml

⚠️ roleRef 建立後不能修改

RoleBinding 或 ClusterRoleBinding 建立後,roleRef 是不可變更的。

如果要改綁定到另一個 Role / ClusterRole,需要刪除原本的 Binding 再重新建立。

綁定關係總覽

https://ithelp.ithome.com.tw/upload/images/20260821/20181928EVwlmzROLw.png


五、驗證權限 — kubectl auth can-i

Kubernetes 提供了 kubectl auth can-i,可以直接測試某個身份是否具備特定權限。

Step 6:測試權限

# dev-user 能不能在 dev-team Namespace 讀取 Pod?
kubectl auth can-i get pods \
  --namespace=dev-team \
  --as=system:serviceaccount:dev-team:dev-user
# → yes

# 能不能刪除 Pod?
kubectl auth can-i delete pods \
  --namespace=dev-team \
  --as=system:serviceaccount:dev-team:dev-user
# → no

# 能不能讀取 default Namespace 的 Pod?
kubectl auth can-i get pods \
  --namespace=default \
  --as=system:serviceaccount:dev-team:dev-user
# → no

最後一個會得到 no,因為我們建立的 Role 只在 dev-team Namespace 內生效。

列出某個身份的權限

kubectl auth can-i --list \
  --namespace=dev-team \
  --as=system:serviceaccount:dev-team:dev-user

可以從結果中確認:

https://ithelp.ithome.com.tw/upload/images/20260821/20181928fgSuOvL5i7.png

代表 dev-user 可以讀取 Pod 與 Pod Log,但沒有刪除 Pod 的權限。

💡 --as 的格式

  • ServiceAccount:--as=system:serviceaccount:<namespace>:<name>
  • User:--as=<username>
  • Group:搭配 --as-group=<groupname>

--as 屬於身份模擬(Impersonation),目前執行指令的身份本身需要有對應的 Impersonation 權限。


六、實戰:讓 Pod 用 ServiceAccount 存取 API

ServiceAccount 很常用來讓 Pod 裡的程式以特定身份存取 Kubernetes API

例如監控系統可能需要讀取 Pod 資訊,CI/CD 可能需要部署到指定 Namespace。

Step 7:建立使用特定 ServiceAccount 的 Pod

vim sa-test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sa-test
  namespace: dev-team
spec:
  serviceAccountName: dev-user
  containers:
    - name: kubectl
      image: bitnami/kubectl:latest
      command: ["sleep", "3600"]

建立 Pod:

kubectl apply -f sa-test-pod.yaml

Step 8:從 Pod 內部測試權限

先進入 Pod:

kubectl exec -it sa-test -n dev-team -- bash

接著在 Pod 內測試:

# 可以讀取 dev-team Namespace 的 Pod
kubectl get pods -n dev-team

應該可以正常列出 Pod。

再測試其他 Namespace:

kubectl get pods -n default

會得到 Forbidden,因為 dev-user 沒有 default Namespace 的權限。

最後測試刪除 Pod:

kubectl delete pod sa-test -n dev-team

同樣會得到 Forbidden,因為我們只授予了讀取權限,沒有 delete 權限。

離開 Pod:

exit

https://ithelp.ithome.com.tw/upload/images/20260821/20181928uQny9xXpR4.png

📝 Pod 如何取得 ServiceAccount Credential?

預設情況下,Kubernetes 會把 ServiceAccount 的 Credential 掛載到 Pod:

/var/run/secrets/kubernetes.io/serviceaccount/

kubectl 或 Kubernetes Client Library 可以利用這些資訊向 API Server 驗證身份。

如果 Pod 不需要存取 Kubernetes API,也可以關閉自動掛載:

automountServiceAccountToken: false

七、內建的 ClusterRole

Kubernetes 預設提供了幾個常用的 ClusterRole,可以直接拿來授權:

kubectl get clusterroles | grep -E "^(admin|edit|view|cluster-admin)"

https://ithelp.ithome.com.tw/upload/images/20260821/20181928ZKo6rS7HyD.png

ClusterRole 權限 適合誰
cluster-admin 對叢集內所有資源執行所有操作 叢集管理員
admin Namespace 內大多數資源的完整管理權限,包含建立 Role / RoleBinding Namespace 管理員
edit Namespace 內大多數資源的讀寫權限,但不能管理 Role / RoleBinding 開發者
view Namespace 內大多數資源的唯讀權限,但不能讀取 Secret 唯讀使用者

Step 9:用內建 ClusterRole 快速授權

kubectl create rolebinding dev-edit \
  --clusterrole=edit \
  --serviceaccount=dev-team:dev-user \
  --namespace=dev-team

這樣 dev-user 就能在 dev-team Namespace 中使用 edit ClusterRole 所定義的權限。

💡 ClusterRole 也可以搭配 RoleBinding

這樣可以重用 ClusterRole 的權限定義,但實際授權範圍仍限制在 RoleBinding 所在的 Namespace。


八、最小權限原則 — 實務建議

🔒 Principle of Least Privilege(最小權限原則)

只授予完成任務所需要的最小權限,避免給予不必要的存取能力。

常見的權限設計模式

場景 建議做法
開發者日常操作 使用 edit ClusterRole + RoleBinding,把權限限制在指定 Namespace
CI/CD Pipeline 建立專用 ServiceAccount 與 Role,只授予部署流程實際需要的操作
監控系統 ClusterRole 只給需要的 get / list / watch,再搭配 ClusterRoleBinding
應用程式讀取 ConfigMap 自訂 Role,只允許讀取需要的 ConfigMap
除錯 / On-call 臨時授權,需要結束後移除

避免常見的安全陷阱

  • 不要隨意使用 cluster-admin —— 除非真的需要叢集最高權限
  • 盡量避免 * Wildcard —— 未來新增的 Resource 也可能一起獲得權限
  • 不要把高權限綁給 default ServiceAccount
  • 不同應用建立專屬 ServiceAccount
  • 不需要存取 Kubernetes API 的 Pod,可關閉 ServiceAccount Token 自動掛載
  • 定期檢查 Role、Binding 與 ServiceAccount 權限

九、常見問題與注意事項

問題 原因與解法
Error from server (Forbidden): ... kubectl auth can-i 確認目前身份是否具備對應權限
RoleBinding 建了但權限沒生效 檢查 namespacesubjectsroleRef 是否正確
想修改 RoleBinding 的 roleRef roleRef 建立後不能修改,需要刪除重建
Pod 裡的程式收到 403 Forbidden 檢查 serviceAccountName 與對應的 RoleBinding

小結

今天我們學會了 Kubernetes 的核心權限控制機制 —— RBAC,了解如何控制「誰可以對哪些資源執行哪些操作」。

重點 說明
RBAC 四個核心資源 Role、ClusterRole、RoleBinding、ClusterRoleBinding
Role vs ClusterRole Role 用於 Namespace 範圍;ClusterRole 可定義叢集層級或可重用的權限
ServiceAccount Pod 存取 Kubernetes API 時常用的身份
kubectl auth can-i 用來驗證權限,也可以搭配 --as 模擬不同身份
內建 ClusterRole cluster-adminadmineditview 提供常見的權限層級
最小權限原則 只授予完成任務所需要的最小權限

學會 RBAC 之後,下一篇我們繼續深入 Kubernetes 安全性 —— NetworkPolicy(網路策略),學習如何控制 Pod 之間的網路流量與存取範圍!


參考資源


上一篇
Day 23|Helm Repository 與 Chart 依賴管理
系列文
從零到 CKA:30 天掌握 Kubernetes 核心觀念與實作24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言